import pygame
import sys
import traceback
import random
import myplane
import enemy
import bullet
import supply

pygame.init()
pygame.mixer.init()

BLACK=(0,0,0)
WHITE=(255,255,255)
RED=(255,0,0)
GREEN =(0,255,0)
size = width,height = 480,700
screen=pygame.display.set_mode(size)
######一定记得要写标题########
pygame.display.set_caption('飞机大战')
background=pygame.image.load('images/background.png').convert_alpha()
again = pygame.image.load('images/again.png').convert_alpha()
again_rect=again.get_rect()

gameover=pygame.image.load('images/gameover.png').convert_alpha()
gameover_rect = gameover.get_rect()

best_score= 666
# 载入游戏音乐
pygame.mixer.music.load("sound/game_music.ogg")
pygame.mixer.music.set_volume(0.2)
bullet_sound = pygame.mixer.Sound("sound/bullet.wav")
bullet_sound.set_volume(0.2)
bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav")
bomb_sound.set_volume(0.2)
supply_sound = pygame.mixer.Sound("sound/supply.wav")
supply_sound.set_volume(0.2)
get_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav")
get_bomb_sound.set_volume(0.2)
get_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav")
get_bullet_sound.set_volume(0.2)
upgrade_sound = pygame.mixer.Sound("sound/upgrade.wav")
upgrade_sound.set_volume(0.2)
enemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav")
enemy3_fly_sound.set_volume(0.2)
enemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav")
enemy1_down_sound.set_volume(0.1)
enemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav")
enemy2_down_sound.set_volume(0.2)
enemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav")
enemy3_down_sound.set_volume(0.5)
me_down_sound = pygame.mixer.Sound("sound/me_down.wav")
me_down_sound.set_volume(0.2)
def add_smallenemy(group1,group2,num):
    for i in range(num):
        e1=enemy.Smallenemy(size)
        group1.add(e1)
        group2.add(e1)
def add_midenemy(group1,group2,num):
    for i in range(num):
        e2=enemy.Midenemy(size)
        group1.add(e2)
        group2.add(e2)
def add_bigenemy(group1,group2,num):
    for i in range(num):
        e3=enemy.Bigenemy(size)
        group1.add(e3)
        group2.add(e3)
def inc_speed(group1,num):
    for each in group1:
        each.speed+=num

def main():
    #各种初始化
    pygame.mixer.music.play(-1)
    clock= pygame.time.Clock()
    
    #生成我方飞机
    me=myplane.Myplane(size)
    #生成敌机组
    enemys = pygame.sprite.Group()
    #生成小飞机
    smallenemys = pygame.sprite.Group()
    add_smallenemy(enemys,smallenemys,15)
    #生成中飞机
    midenemys = pygame.sprite.Group()
    add_midenemy(enemys,midenemys,6)
    #生成大飞机
    bigenemys = pygame.sprite.Group()
    add_bigenemy(enemys,bigenemys,2)
    #生命
    life = pygame.image.load('images/life.png').convert_alpha()
    life_rect = life.get_rect()
    life_num = 3
    #生成普通子弹
    bullets = []
    bullet1 = []
    bullet1_index=0
    BULLET1_NUM = 4
    for i in range(BULLET1_NUM ):
        bullet1.append(bullet.Bullet1(me.rect.midtop))
        
    #生成超级子弹
    bullet2 = []
    bullet2_index=0
    BULLET2_NUM = 8
    for i in range(BULLET2_NUM //2):
        bullet2.append(bullet.Bullet2((me.rect.centerx-33,me.rect.centery)))
        bullet2.append(bullet.Bullet2((me.rect.centerx+30,me.rect.centery)))
    #生成补给
    bullet_supply=supply.Bullet_supply(size)
    bomp_supply=supply.Bomp_supply(size)
    #统计得分
    score=0
    score_font = pygame.font.Font('font/font.ttf',36)
    #难度
    leve=1
    #全屏炸弹
    bomb_image = pygame.image.load("images/bomb.png").convert_alpha()
    bomb_rect = bomb_image.get_rect()
    bomb_font = pygame.font.Font("font/font.ttf", 48)
    bomb_num = 3
    #画所有
    draw=[]
    draw_line=[]
    draw_enemy=[]
    #暂停
    pause = False
    pause_nor_image=pygame.image.load('images/pause_nor.png').convert_alpha()
    pause_pressed_image=pygame.image.load('images/pause_pressed.png').convert_alpha()
    resume_nor_image=pygame.image.load('images/resume_nor.png').convert_alpha()
    resume_pressed_image=pygame.image.load('images/resume_pressed.png').convert_alpha()
    pause_image = pause_nor_image
    pause_rect=pause_nor_image.get_rect()
    pause_rect.left,pause_rect.top = (width-pause_rect.width-10),10
    #延时
    delay = 100
    SUPPLAY_TIME = pygame.USEREVENT
    pygame.time.set_timer(SUPPLAY_TIME,30*1000)

    BULLET_TIME = pygame.USEREVENT+1
    pygame.time.set_timer(SUPPLAY_TIME,10*1000)

    WUDI_TIME = pygame.USEREVENT+2

    recorded=False
    is_bullet = False
    switch = False
    runing=True
    while runing:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1 and pause_rect.collidepoint(event.pos):
                    pause  =not pause
                    if pause:
                        pygame.time.set_timer(SUPPLAY_TIME,0)
                        pygame.mixer.music.pause()
                        pygame.mixer.pause()
                    else:
                        pygame.time.set_timer(SUPPLAY_TIME,30*1000)
                        pygame.mixer.music.unpause()
                        pygame.mixer.unpause()
                        
            elif event.type == pygame.MOUSEMOTION:
                if pause_rect.collidepoint(event.pos):
                    if pause:
                        pause_image = resume_pressed_image
                    else:
                        pause_image =pause_pressed_image
                else:
                    if pause:
                        pause_image = resume_nor_image
                    else:
                        pause_image =pause_nor_image
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if bomb_num:
                        bomb_num -= 1
                        bomb_sound.play()
                        for each in enemys:
                            if each.rect.bottom > 0:
                                each.active = False
            elif event.type == SUPPLAY_TIME:
                supply_sound.play()
                if random.choice([True,False]):
                    bullet_supply.reset()
                else:
                    bomp_supply.reset()
            elif event.type == BULLET_TIME:
                is_bullet = False
                pygame.time.set_timer(BULLET_TIME,0)
            elif event.type == WUDI_TIME:
                me.wudi = False
                pygame.time.set_timer(WUDI_TIME,0)
                
                        
        if leve == 1 and score > 50000:
            leve =2
            upgrade_sound.play()
            #增加敌机数量
            add_smallenemy(enemys,smallenemys,5)
            add_midenemy(enemys,midenemys,2)
            add_bigenemy(enemys,bigenemys,1)
            #增加飞机速度
            inc_speed(smallenemys,1)
        elif leve == 2 and score > 300000:
            leve =3
            upgrade_sound.play()
            #增加敌机数量
            add_smallenemy(enemys,smallenemys,5)
            add_midenemy(enemys,midenemys,2)
            add_bigenemy(enemys,bigenemys,1)
            #增加飞机速度
            inc_speed(smallenemys,1)
        elif leve == 3 and score > 1000000:
            leve =4
            upgrade_sound.play()
            #增加敌机数量
            add_smallenemy(enemys,smallenemys,5)
            add_midenemy(enemys,midenemys,2)
            add_bigenemy(enemys,bigenemys,1)
            #增加飞机速度
            inc_speed(smallenemys,1)
            inc_speed(midenemys,1)
        elif leve == 4 and score > 2000000:
            leve =5
            upgrade_sound.play()
            #增加敌机数量
            add_smallenemy(enemys,smallenemys,5)
            add_midenemy(enemys,midenemys,2)
            add_bigenemy(enemys,bigenemys,1)
            #增加飞机速度
            inc_speed(smallenemys,1)
            inc_speed(midenemys,1)
            
        #设定延时 5帧翻转一次(煞笔 有问题)
        #if delay:
        #   delay-=1
        #else:
        #    delay=100
        #设定延时
        delay -= 1
        if not delay:
            delay = 100
        if not (delay%5):
            switch = not switch

        if life_num and not pause:
            draw=[]
            draw_line=[]
            draw_enemy=[]
            key_pressed = pygame.key.get_pressed()
            if key_pressed[pygame.K_w] or key_pressed[pygame.K_UP]:
                me.moveup()
            if key_pressed[pygame.K_s] or key_pressed[pygame.K_DOWN]:
                me.movedown()
            if key_pressed[pygame.K_a] or key_pressed[pygame.K_LEFT]:
                me.moveleft()
            if key_pressed[pygame.K_d] or key_pressed[pygame.K_RIGHT]:
                me.moveright()
            #检测全屏炸弹
            if bomp_supply.active:
                bomp_supply.move()
                draw.append((bomp_supply.image2,bomp_supply.rect))
                if pygame.sprite.collide_mask(bomp_supply,me):
                    get_bomb_sound.play()
                    if bomb_num < 3:
                        bomb_num +=1
                    bomp_supply.active = False

            #检测超级子弹
            if bullet_supply.active:
                bullet_supply.move()
                draw.append((bullet_supply.image1,bullet_supply.rect))
                if pygame.sprite.collide_mask(bullet_supply,me):
                    get_bullet_sound.play()
                    is_bullet =True
                    pygame.time.set_timer(BULLET_TIME,18*1000)
                    bullet_supply.active = False
                    
                    
                    
            #画子弹_发射子弹
            if not (delay%10):
                bullet_sound.play()
                if is_bullet:
                    bullets=bullet2
                    bullets[bullet2_index].reset((me.rect.centerx-33,me.rect.centery))
                    bullets[bullet2_index+1].reset((me.rect.centerx+30,me.rect.centery))
                    bullet2_index = (bullet2_index+2) % BULLET2_NUM
                    
 
                else:
                    bullets=bullet1
                    bullets[bullet1_index].reset(me.rect.midtop)
                    bullet1_index = (bullet1_index+1) % BULLET1_NUM
                    
            #画子弹_子弹飞行
            for b in bullets:
                if b.active:
                    b.move()
                    draw.append((b.image,b.rect))
                    enemy_hit = pygame.sprite.spritecollide(b,enemys,False,\
                                                            pygame.sprite.collide_mask)
                    if enemy_hit:
                        b.active =False
                        for e in enemy_hit:
                            if e in midenemys or e in bigenemys:
                                e.hit = True
                                e.HP-=1
                                if e.HP == 0:
                                    e.active = False
                            else:
                                e.active = False

                    
            #画大飞机
            for each in bigenemys:
                if each.active:
                    each.move()
                    draw_line.append((BLACK,\
                                      (each.rect.left,each.rect.top-5),\
                                      (each.rect.right,each.rect.top-5),2))
                    bl=each.HP/enemy.Bigenemy.HP
                    if bl > 0.2:
                        color = GREEN
                    else :
                        color = RED
                    draw_line.append((color,\
                                     (each.rect.left,each.rect.top-5),\
                                     (each.rect.left+bl*each.rect.width,each.rect.top-5),2))
                    if each.rect.bottom == -50:
                        enemy3_fly_sound.play(-1)
                    if each.hit:
                        draw_enemy.append((each.hit_image,each.rect))
                        each.hit=False
                    else:
                        if switch:
                            draw_enemy.append((each.image1,each.rect))
                        else:
                            draw_enemy.append((each.image2,each.rect))
                #毁灭
                else:
                    if not (delay%3):
                        if not (each.index%6):
                            enemy3_down_sound.play()
                        draw_enemy.append((each.image_downs[each.index],each.rect))
                        each.index+=1
                        if not (each.index%6):
                            score+=each.score
                            each.reset()
                            enemy3_fly_sound.stop()
            #画中飞机
            for each in midenemys:
                if each.active:
                    each.move()
                    if each.hit :
                        draw_enemy.append((each.hit_image,each.rect))
                        each.hit=False
                    else:
                        draw_enemy.append((each.image,each.rect))
                    draw_line.append((BLACK,\
                        (each.rect.left,each.rect.top-5),\
                                     (each.rect.right,each.rect.top-5),2)) 
                    bl=each.HP/enemy.Midenemy.HP
                    if bl > 0.2:
                        color = GREEN
                    else :
                        color = RED
                    draw_line.append((color,\
                                     (each.rect.left,each.rect.top-5),\
                                     (each.rect.left+bl*each.rect.width,each.rect.top-5),2))
                #毁灭
                else:
                    if not (delay%3):
                        if not (each.index%4):
                            enemy2_down_sound.play()
                        draw_enemy.append((each.image_downs[each.index],each.rect))
                        each.index+=1
                        if not (each.index%4):
                            score+=each.score
                            each.reset()
                
            #画小飞机
            for each in smallenemys:
                if each.active:
                    each.move()
                    draw_enemy.append((each.image,each.rect))
                #毁灭
                else:
                    if not (delay%3):
                        if not (each.index%4):
                            enemy1_down_sound.play()
                        draw_enemy.append((each.image_downs[each.index],each.rect))
                        each.index+=1
                        if not (each.index%4):
                            score+=each.score
                            each.reset()
            #检测碰撞
            enemys_down = pygame.sprite.spritecollide(me,enemys,False,pygame.sprite.collide_mask)
            if enemys_down:
                if not me.wudi:
                    me.active = False
                for i in enemys_down:
                    i.active = False
            # 绘制全屏炸弹数量
            bomb_text = bomb_font.render("× %d" % bomb_num, True, WHITE)
            text_rect = bomb_text.get_rect()
            draw.append((bomb_image, (10, height - 10 - bomb_rect.height)))
            draw.append((bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height)))
            #显示得分
            score_text=score_font.render('Score : %s'%str(score),True,WHITE)
            draw.append((score_text,(10,5)))
            #显示生命
            if life_num:
                for i in range(life_num):
                    draw.append((life,(width - 10-\
                                 (i+1)*life_rect.width,height-life_rect.height)))
            #画自己的飞机
            if me.active:
                if switch:
                    draw.append((me.image1,me.rect))
                else:
                    draw.append((me.image2,me.rect))
            #毁灭
            else:
                if not (delay%3):
                    if  me.index == 0:
                        me_down_sound.play()
                    draw.append((me.image_downs[me.index],me.rect))
                    me.index=(me.index+1)%4
                    if me.index == 0:
                        life_num-=1
                        me.reset()
                        pygame.time.set_timer(WUDI_TIME,3*1000)
            
        
        screen.blit(background,(0,0))
        screen.blit(pause_image,pause_rect)
        if life_num == 0:
            pause = True
            pygame.time.set_timer(SUPPLAY_TIME,30*1000)
            pygame.mixer.pause()
            pygame.mixer.music.pause()
            if not recorded:
                recorded=True
                # 读取历史最高得分
                with open("record.txt", "r") as f:
                    best_score = int(f.read())

                # 如果玩家得分高于历史最高得分，则存档
                if score > best_score:
                    best_score=score
                    with open("record.txt", "w") as f:
                        f.write(str(score))
            #绘制结束背景
            screen.blit(background,(0,0))
            best_score_text = score_font.render('Best : %s'%(best_score),True,(255,255,255))
            best_score_rect = best_score_text.get_rect()
            best_score_rect.left,best_score_rect.top = 50,50
            screen.blit(best_score_text,best_score_rect)

            gameover_font = pygame.font.Font("font/font.TTF", 48)
            score_text1 = gameover_font.render("Your Score", True, (255, 255, 255))
            score_rect1 = score_text1.get_rect()
            score_rect1.left, score_rect1.top = \
                                 (width - score_rect1.width) // 2, height // 3
            screen.blit(score_text1,score_rect1)

            score_text2 = gameover_font.render(str(score), True, (255, 255, 255))
            score_rect2 = score_text2.get_rect()
            score_rect2.left, score_rect2.top = \
                                 (width - score_rect2.width) // 2, \
                                 score_rect1.bottom + 10
            screen.blit(score_text2,score_rect2)
            
            again_rect.left, again_rect.top = \
                             (width - again_rect.width) // 2, \
                             score_rect2.bottom + 50                  
            screen.blit(again,again_rect)
            
            gameover_rect.left, gameover_rect.top = \
                                (width - again_rect.width) // 2, \
                                again_rect.bottom + 10
            screen.blit(gameover,gameover_rect)
            # 检测用户的鼠标操作
            # 如果用户按下鼠标左键
            if pygame.mouse.get_pressed()[0]:
                # 获取鼠标坐标
                pos = pygame.mouse.get_pos()
                # 如果用户点击“重新开始”
                if again_rect.left < pos[0] < again_rect.right and \
                   again_rect.top < pos[1] < again_rect.bottom:
                    # 调用main函数，重新开始游戏
                    main()
                # 如果用户点击“结束游戏”            
                elif gameover_rect.left < pos[0] < gameover_rect.right and \
                     gameover_rect.top < pos[1] < gameover_rect.bottom:
                    # 退出游戏
                    pygame.quit()
                    sys.exit()

            
        else:
            for i,j in draw:
                screen.blit(i,j)
            for i,j in draw_enemy:
                screen.blit(i,j)
            for a,b,c,d in draw_line:
                pygame.draw.line(screen,a,b,c,d)
        pygame.display.flip()
        clock.tick(60)


if __name__=='__main__':
    try:
        main()
    except SystemExit:
        pass
    except:
        traceback.print_exc()
        pygame.quit()
        input()
